package com.example.moneygrosService.handlers;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import android.content.AsyncQueryHandler;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.BaseColumns;
import android.util.Log;
import android.widget.Toast;

import com.example.moneygrosService.MainActivityService.DB_TOKEN;
import com.example.moneygrosService.User;
import com.example.moneygrosService.database.MoneyContract;
import com.example.moneygrosService.database.MoneyContract.Users;
import com.example.moneygrosService.database.MoneyContract.UsersColumns;
import com.example.moneygrosService.handlers.ResultListener.ResultType;

public class ManageContactHandler extends AsyncQueryHandler {
	private static final String TAG = "ManageContactHandler";
	
	private Bundle mBundle;
	private User mUser;
	private ContentResolver mCr;
	
	private boolean mUserInserted=false;
	private boolean mResult;
	
	private final Lock mLock = new ReentrantLock();
	private Condition mResultOKCond = mLock.newCondition();
	private boolean mResultOK;
	
	private ResultListener mListener;
	
	public ManageContactHandler(ContentResolver cr, Bundle bundle) {
		super(cr);
		// TODO Auto-generated constructor stub
		mCr= cr;
		mBundle = bundle;
		mUser = new User();
		mUser.setUser_id(bundle.getString(UsersColumns.USER_ID));
		mUser.setUser_name(bundle.getString(UsersColumns.USER_NAME));
		mUser.setPhone_number(bundle.getString(UsersColumns.PHONE_NUMBER));
		mUser.setBluetooth_MAC(bundle.getString(UsersColumns.BLUETOOTH_MAC));
		mUser.setBidirectional(bundle.getBoolean(UsersColumns.BIDIRECTIONAL,false));
		mUser.setBalance(0);
		mUser.setVersion(bundle.getString(UsersColumns.VERSION,"1"));
	}

	public ManageContactHandler(ContentResolver cr, User user) {
		super(cr);
		// TODO Auto-generated constructor stub
		mCr= cr;
		mUser = user;
	}
	
	public void manageUser(){
		InsertOrUpdateContactHandler checkAndInsertUserHandler = new InsertOrUpdateContactHandler(mCr);
        checkAndInsertUserHandler.checkContactExistence();
	}


	protected void userInserted(boolean insert){
		mResultOK = true;
		mResult = insert;
		mUserInserted = insert;

		if(mListener!=null)
			mListener.onResult(insert, ResultType.USER_INSERTED, null);
	}
	
	public class InsertOrUpdateContactHandler extends AsyncQueryHandler {
		private static final String TAG = "InsertOrUpdateContactHandler";
		
		public InsertOrUpdateContactHandler(ContentResolver cr) {
			super(cr);
		}
		
		public void checkContactExistence(){
			String[] projection = {BaseColumns._ID, MoneyContract.UsersColumns.USER_ID, MoneyContract.UsersColumns.VERSION};
			String selection = MoneyContract.UsersColumns.USER_ID+"=?";
			String[] selectionArgs= {mUser.getUser_id()};
			startQuery(DB_TOKEN.CHECK_USER_FOR_INSERT, (Object) mUser, Users.CONTENT_URI, projection, selection, selectionArgs, null);
		}

		private void insertUser(User user) {
			// TODO Auto-generated method stub		
	        ContentValues values = user.getContentValues();
			startInsert(DB_TOKEN.INSERT_USER, (Object)user,Users.CONTENT_URI, values);
		}

		private void updateUser(User user) {
			// TODO Auto-generated method stub		
	        ContentValues values = user.getContentValues();
	        String selection = MoneyContract.UsersColumns.USER_ID+"=?";
			String[] selectionArgs= {user.getUser_id()};
			startUpdate(DB_TOKEN.UPDATE_USER, (Object)user, Users.CONTENT_URI, values, selection, selectionArgs);
		}

		/* (non-Javadoc)
		 * @see android.content.AsyncQueryHandler#onInsertComplete(int, java.lang.Object, android.net.Uri)
		 */
		@Override
		protected void onInsertComplete(int token, Object cookie, Uri uri) {
	   		switch(token){
    		case DB_TOKEN.INSERT_USER:
    			Log.v(TAG, "User "+((User)cookie).getUser_id()+" inserted.");
    			// ce code est rendu obsolete par le jumelage des tables USERS et BALANCCES
//    			Balance balance= new Balance(((User)cookie).getUser_id(), 0, "1.0");
//    			insertBalance(balance);
    			userInserted(true);
    			break;
    		}
		}

		
		
		/* (non-Javadoc)
		 * @see android.content.AsyncQueryHandler#onQueryComplete(int, java.lang.Object, android.database.Cursor)
		 */
		@Override
		protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
			// TODO Auto-generated method stub
    		switch(token){

    		case DB_TOKEN.CHECK_USER_FOR_INSERT:
    			Log.v(TAG, "CHECK_USER_FOR_INSERT");
    			if(cursor != null){
    				if(cursor.getCount() == 0){
    					cursor.close();
    	    			Log.v(TAG, "inserting user");
    					insertUser((User)mUser);
//    					insertUser((User)cookie);
    				} else {
    					cursor.moveToFirst();

    					String existingUserVersion = cursor.getString(cursor.getColumnIndex(MoneyContract.UsersColumns.VERSION));

    					if(Integer.parseInt(existingUserVersion) < Integer.parseInt(mUser.getVersion())){
        	    			Log.v(TAG, "updating user");
        					updateUser((User)mUser);
    	    			} else {
        	    			Log.v(TAG, "user up-to-date");
    	    				if(mListener!=null)
    	    					mListener.onResult(false, ResultType.EXISTING_USER, null);
    	    			}
    				}
    			}    				
        		break;
    		}
		}

		/* (non-Javadoc)
		 * @see android.content.AsyncQueryHandler#onUpdateComplete(int, java.lang.Object, int)
		 */
		@Override
		protected void onUpdateComplete(int token, Object cookie, int result) {
			// TODO Auto-generated method stub
			switch(token){
    		case DB_TOKEN.UPDATE_USER:
    			Log.v(TAG, "User "+((User)cookie).getUser_id()+" updated.");
    			// ce code est rendu obsolete par le jumelage des tables USERS et BALANCCES
//    			Balance balance= new Balance(((User)cookie).getUser_id(), 0, "1.0");
//    			insertBalance(balance);
    			userInserted(true);
    			break;
    		}
		}
		
	}


	/* (non-Javadoc)
	 * @see android.content.AsyncQueryHandler#startQuery(int, java.lang.Object, android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String)
	 */
	@Override
	public void startQuery(int token, Object cookie, Uri uri,
			String[] projection, String selection, String[] selectionArgs,
			String orderBy) {
		// TODO Auto-generated method stub
		super.startQuery(token, cookie, uri, projection, selection, selectionArgs,
				orderBy);
	}

	public void addResultListener(ResultListener obj) {
		// TODO Auto-generated method stub
		mListener = obj;		
	}

}
